package com.ifeng.shopping.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.util.Log;

public class ImageGetForHttp {
	// ͼƬ���С����
	public final static int IMAGE_SIZE_COMPRESS = 200 * 1024;
	private final static int TIMEOUT = 60;
	private static final int IO_BUFFER_SIZE = 4 * 1024;
	
	public static Bitmap downloadBitmap(String url) {
		
		final HttpParams params = createHttpParams();
		final HttpGet request = new HttpGet(url);
		final HttpClient httpClient = new DefaultHttpClient(params);
		
		
		try{
			
			HttpHost proxy = null;
			Log.v("ImageGetForHttp", "����ͼƬ����ʽ��"+ NetUtils.CURRECT_NET_WORK_TYPE);
			Log.v("ImageGetForHttp", "����ͼƬ��ַ��" + url);
			
			switch (NetUtils.CURRECT_NET_WORK_TYPE) {
			
			case  NetUtils.TYPE_CT_WAP:
				proxy = new HttpHost("10.0.0.200", 80, "http");
				httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
				break;
			
			case  NetUtils.TYPE_CM_CU_WAP:
				proxy = new HttpHost("10.0.0.172", 80,"http");
				httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
				
				break;
			
			}
			
			
			HttpResponse response = httpClient.execute(request);
			StatusLine statusLine = response.getStatusLine();
			
			if(statusLine != null){
				
				final int statusCode = statusLine.getStatusCode();
				if(statusCode != HttpStatus.SC_OK){
					return null;
				}else{
					
					HttpEntity entity = response.getEntity();
					BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
					
					if(bufHttpEntity != null){
						long length = bufHttpEntity.getContentLength();
						
						if(length > 0){
							InputStream inStream = null;
							
							try{
								inStream = bufHttpEntity.getContent();
								return getBitmap(url, inStream, length);
								
							}catch (Exception e) {
								e.printStackTrace();
							}
						}
					}
				}
			}
			
		}catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return null;
	}
	
	private static HttpParams createHttpParams() {
		final HttpParams params = new BasicHttpParams();
		HttpConnectionParams.setStaleCheckingEnabled(params, false);
		HttpConnectionParams.setConnectionTimeout(params, TIMEOUT * 1000);
		HttpConnectionParams.setSoTimeout(params, TIMEOUT * 1000);
		HttpConnectionParams.setSocketBufferSize(params, 8192 * 5);
		return params;
	}
	
	
	private static synchronized Bitmap getBitmap(String url, InputStream is,long len) {
		
		Bitmap bitmap = null;
		byte[] data;
		
		InputStream inStream = null;
		OutputStream outputStream = null;
		
		// ���decoder->decode returned false���ⷽʽ�ģ�
		
		FlushedInputStream flushedInputStream = null;
		try{
			if(is != null){
				flushedInputStream = new FlushedInputStream(is);
				if(len > IMAGE_SIZE_COMPRESS){
					bitmap = BitmapFactory.decodeStream(flushedInputStream, null, getCompressOpt());
				}else{
					bitmap = BitmapFactory.decodeStream(flushedInputStream);
				}
				
				Log.v("ImageGetForHttp", "imageUrl ==4=== " + url + ", bitmap "+ bitmap);
						
				if(bitmap != null){
					return bitmap;
				}
			}
			
		}catch (OutOfMemoryError e) {
			Log.v("ImageGetForHttp", "error 4 " + e.toString());
			e.printStackTrace();
			
			if(bitmap != null && !bitmap.isRecycled()){
				bitmap.recycle();
				bitmap = null;
			}
			
		}catch (Exception e) {
			Log.v("ImageGetForHttp", "error 4 " + e.toString());
			e.printStackTrace();
			
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
			
		}finally {
			try{
				
				if(flushedInputStream != null){
					flushedInputStream.close();
				}
				
			}catch (Exception e) {
				e.printStackTrace();
			}
			flushedInputStream = null;
		}
		
		// ���decoder->decode returned false���ⷽʽ�ߣ�
		try{
			
			if (is != null) {
				final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
				outputStream = new BufferedOutputStream(byteArrayOutputStream,IO_BUFFER_SIZE);
				copy(is, outputStream);
				outputStream.flush();
				
				data = byteArrayOutputStream.toByteArray();
				
				if (data != null) {
					if (len > IMAGE_SIZE_COMPRESS) {
						bitmap = BitmapFactory.decodeByteArray(data, 0,
								data.length, getCompressOpt());
					} else {
						bitmap = BitmapFactory.decodeByteArray(data, 0,
								data.length);
					}

					Log.v("ImageGetForHttp", "imageUrl ==7=== " + url+ ", bitmap " + bitmap);
							

					if (bitmap != null) {
						return bitmap;
					}
				}
			}
			
			
		} catch (OutOfMemoryError e) {
			Log.v("ImageGetForHttp", "error 7 " + e.toString());
			e.printStackTrace();
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		} catch (Exception e) {
			Log.v("ImageGetForHttp", "error 7 " + e.toString());
			e.printStackTrace();
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		} finally {
			try {
				if (outputStream != null) {
					outputStream.close();
				}
			} catch (IOException e) {
			}
		}
		
		// ���decoder->decode returned false���ⷽʽ��
		try {
			if (is != null) {
				data = readStream(is);
				if (data != null) {
					if (len > IMAGE_SIZE_COMPRESS) {
						bitmap = BitmapFactory.decodeByteArray(data, 0,
								data.length, getCompressOpt());
					} else {
						bitmap = BitmapFactory.decodeByteArray(data, 0,
								data.length);
					}
					Log.v("ImageFileCache", "imageUrl ==6=== " + url
							+ ", bitmap " + bitmap);

					if (bitmap != null) {
						return bitmap;
					}
				}
			}
		} catch (Exception e) {
			Log.v("ImageGetForHttp", "error 6 " + e.toString());
			e.printStackTrace();
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		} catch (OutOfMemoryError e) {
			Log.v("ImageGetForHttp", "error 6 " + e.toString());
			e.printStackTrace();
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		} finally {
			data = null;
		}
		
		// ���decoder->decode returned false���ⷽʽһ��
		try {
			// final URLConnection conn = new URL(url).openConnection();
			// conn.connect();
			// final InputStream isStream = conn.getInputStream();
			final URL m = new URL(url);
			inStream = (InputStream) m.getContent();
			if (inStream != null) {
				data = readStream(inStream);
				if (data != null) {
					if (len > IMAGE_SIZE_COMPRESS) {
						bitmap = BitmapFactory.decodeByteArray(data, 0,
								data.length, getCompressOpt());
					} else {
						bitmap = BitmapFactory.decodeByteArray(data, 0,
								data.length);
					}

					Log.v("ImageGetForHttp", "imageUrl ==1=== " + url
							+ ", bitmap " + bitmap);

					if (bitmap != null) {
						return bitmap;
					}
				}
			}
		} catch (Exception e) {
			Log.v("ImageGetForHttp", "error 1 " + e.toString());
			e.printStackTrace();
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		} catch (OutOfMemoryError e) {
			Log.v("ImageGetForHttp", "error 1 " + e.toString());
			e.printStackTrace();
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		} finally {
			try {
				if (inStream != null) {
					inStream.close();
				}
			} catch (IOException e) {
			}
			inStream = null;
			data = null;
		}
		
		
		// ���decoder->decode returned false���ⷽʽ����
		ByteArrayOutputStream dataStream = null;
		BufferedOutputStream out = null;
		try {
			inStream = new BufferedInputStream(new URL(url).openStream(), 1024);
			if (inStream != null) {
				dataStream = new ByteArrayOutputStream();
				out = new BufferedOutputStream(dataStream, 1024);
				copy(inStream, out);
				out.flush();
				data = dataStream.toByteArray();
				if (data != null) {
					if (len > IMAGE_SIZE_COMPRESS) {
						bitmap = BitmapFactory.decodeByteArray(data, 0,
								data.length, getCompressOpt());
					} else {
						bitmap = BitmapFactory.decodeByteArray(data, 0,
								data.length);
					}

					Log.v("ImageGetForHttp", "imageUrl ==2=== " + url
							+ ", bitmap " + bitmap);

					if (bitmap != null) {
						return bitmap;
					}
				}
			}
		} catch (Exception e) {
			Log.v("ImageGetForHttp", "error 2 " + e.toString());
			e.printStackTrace();
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		} catch (OutOfMemoryError e) {
			Log.v("ImageGetForHttp", "error 2 " + e.toString());
			e.printStackTrace();
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		} finally {
			try {
				if (out != null) {
					out.close();
				}
				if (dataStream != null) {
					dataStream.close();
				}
				if (inStream != null) {
					inStream.close();
				}
			} catch (IOException e) {
			}
			out = null;
			dataStream = null;
			inStream = null;
			data = null;
		}

		// ���decoder->decode returned false���ⷽʽ��
		try {
			final HttpURLConnection conn = (HttpURLConnection) new URL(url)
					.openConnection();
			conn.setDoInput(true);
			conn.connect();
			inStream = conn.getInputStream();
			if (inStream != null) {
				final int length = (int) conn.getContentLength();
				if (length != -1) {
					data = new byte[length];
					byte[] temp = new byte[512];
					int readLen = 0;
					int destPos = 0;
					while ((readLen = inStream.read(temp)) > 0) {
						System.arraycopy(temp, 0, data, destPos, readLen);
						destPos += readLen;
					}
					if (len > IMAGE_SIZE_COMPRESS) {
						bitmap = BitmapFactory.decodeByteArray(data, 0,
								data.length, getCompressOpt());
					} else {
						bitmap = BitmapFactory.decodeByteArray(data, 0,
								data.length);
					}
					Log.v("ImageGetForHttp", "imageUrl ==3=== " + url
							+ ", bitmap " + bitmap);

					temp = null;

					if (bitmap != null) {
						return bitmap;
					}
				}
			}
		} catch (Exception e) {
			Log.v("ImageGetForHttp", "error 3 " + e.toString());
			e.printStackTrace();
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		} catch (OutOfMemoryError e) {
			Log.v("ImageGetForHttp", "error 3 " + e.toString());
			e.printStackTrace();
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		} finally {
			try {
				if (inStream != null) {
					inStream.close();
				}
			} catch (IOException e) {
			}
			inStream = null;
			data = null;
		}
		
		
		// ���decoder->decode returned false���ⷽʽ�壺
		PlurkInputStream plurkInputStream = null;
		try {
			if (is != null) {
				plurkInputStream = new PlurkInputStream(is);
				if (len > IMAGE_SIZE_COMPRESS) {
					bitmap = BitmapFactory.decodeStream(plurkInputStream, null,
							getCompressOpt());
				} else {
					bitmap = BitmapFactory.decodeStream(plurkInputStream);
				}
				Log.v("ImageFileCache", "imageUrl ==5=== " + url + ", bitmap "
						+ bitmap);

				if (bitmap != null) {
					return bitmap;
				}
			}
		} catch (Exception e) {
			Log.v("ImageFileCache", "error 5 " + e.toString());
			e.printStackTrace();
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		} catch (OutOfMemoryError e) {
			Log.v("ImageFileCache", "error 5 " + e.toString());
			e.printStackTrace();
			if (bitmap != null && !bitmap.isRecycled()) {
				bitmap.recycle();
				bitmap = null;
			}
		} finally {
			try {
				if (plurkInputStream != null) {
					plurkInputStream.close();
				}
			} catch (IOException e) {
			}
			plurkInputStream = null;
		}
		return null;
	}
	
	public static class PlurkInputStream extends FilterInputStream {

		protected PlurkInputStream(InputStream in) {
			super(in);
		}

		@Override
		public int read(byte[] buffer, int offset, int count)
				throws IOException {
			int ret = super.read(buffer, offset, count);
			for (int i = 6; i < buffer.length - 4; i++) {
				if (buffer[i] == 0x2c) {
					if (buffer[i + 2] == 0 && buffer[i + 1] > 0
							&& buffer[i + 1] <= 48) {
						buffer[i + 1] = 0;
					}
					if (buffer[i + 4] == 0 && buffer[i + 3] > 0
							&& buffer[i + 3] <= 48) {
						buffer[i + 3] = 0;
					}
				}
			}
			return ret;
		}

	}
	
	/**
	 * BitmapFactory���decodeStream���������糬ʱ������ʱ���޷���ȡ�������ݣ�
	 * ��������ͨ��̳�FilterInputStream���skip������ǿ��ʵ��flush���е���ݣ�
	 * ��Ҫԭ����Ǽ���Ƿ��ļ�ĩ�ˣ�����http���Ƿ����
	 */
	static class FlushedInputStream extends FilterInputStream {

		protected FlushedInputStream(InputStream in) {
			super(in);
		}
		
		@Override
		public long skip(long byteCount) throws IOException {
			// TODO Auto-generated method stub
			long totalBytesSkipped = 0L;
			while(totalBytesSkipped < byteCount){
				long bytesSkipped = in.skip(byteCount - totalBytesSkipped);
				
				if(bytesSkipped == 0L){
					int b = read();
					if(b < 0){
						break;
					}else{
						bytesSkipped = 1;// we read one byte
					}
				}
				totalBytesSkipped += bytesSkipped;
			}
			
			return totalBytesSkipped;
		}
		
	}
	
	/**
	 * ѹ��ͼƬ
	 * 
	 * @return
	 */
	public static Options getCompressOpt() {
		final Options compressOpt = new BitmapFactory.Options();
		compressOpt.inSampleSize = 3;
		return compressOpt;
	}
	
	
	private static void copy(InputStream in, OutputStream out)throws IOException {
	
		final byte[] b = new byte[IO_BUFFER_SIZE];
		int read;
		while ((read = in.read(b)) != -1) {
			out.write(b, 0, read);
		}
	}
	
	/**
	 * �õ�ͼƬ�ֽ��� �����С
	 * 
	 * @param inStream
	 * @return
	 * @throws Exception
	 */
	private static byte[] readStream(InputStream inStream) throws Exception {
		final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		final byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer, 0, 1024)) != -1) {
			outStream.write(buffer, 0, len);
			outStream.flush();
		}
		outStream.close();
		inStream.close();
		return outStream.toByteArray();
	}

}
